//
// Created by wangwanlong on 2024/6/17.
//

#ifndef MCGPP_RATING_ACCEPTANCE_POLICY_H
#define MCGPP_RATING_ACCEPTANCE_POLICY_H

#include "policy_base.h"
#include "typedef.h"
#include "macros.h"
#include "rating_tie_breaking_policy.h"
#include "fast_reset_flag_array.h"
//缩合顶点选择策略
namespace mcgpp {
  //更喜欢分数最大且本轮没有被匹配过的点，注意此打分函数确保每个点都有匹配对象，即使另一个点本轮以及被匹配了
  template<class TieBreaking = RandomRatingWins>
  class BestRatingPreferringUnmatched final : public meta::PolicyBase {
  public:
    MCGPP_ATTRIBUTE_ALWAYS_INLINE static bool accept(const RatingType tmp_rating,
                                                     const RatingType best_rating,
                                                     const int count,
                                                     const IDType old_target,
                                                     const IDType new_target,
                                                     const ds::FastResetFlagArray<> &already_matched) {

      return tmp_rating > best_rating || (
              (tmp_rating == best_rating) &&
              (
                      (already_matched[old_target] && !already_matched[new_target]) ||
                      (already_matched[old_target] && already_matched[new_target] &&
                       TieBreaking::acceptEqual(count)) ||
                      (!already_matched[old_target] && !already_matched[new_target] &&
                       TieBreaking::acceptEqual(count))
              )
      );
    }

  };

  //这里只考虑没有被匹配的点
  template<class TieBreaking = RandomRatingWins>
  class BestRatingOnlyUnmatched final : public meta::PolicyBase {
  public:
    MCGPP_ATTRIBUTE_ALWAYS_INLINE static bool accept(const RatingType tmp_rating,
                                                     const RatingType best_rating,
                                                     const int count,
                                                     const IDType _,
                                                     const IDType new_target,
                                                     const ds::FastResetFlagArray<> &already_matched) {

      return !already_matched[new_target] &&
             (
                     (tmp_rating > best_rating )
                     || (tmp_rating == best_rating &&
                         TieBreaking::acceptEqual(count)
                     )
             );
    }

  };


}
#endif //MCGPP_RATING_ACCEPTANCE_POLICY_H
